package com.service.scheduler.server;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobKey;
import org.quartz.JobListener;
import org.quartz.Matcher;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.KeyMatcher;
import com.service.cache.CacheManager;
import com.service.other.Logger;
import com.service.scheduler.sched.BaiduApiSched;
import com.service.scheduler.sched.CacheSched;
import com.service.scheduler.sched.DutySched;
import com.service.scheduler.sched.FuelConsumptionAlarmSched;
import com.service.scheduler.sched.GarbageDataSyncSched;
import com.service.scheduler.sched.NoticeMessageSched;
import com.service.scheduler.sched.OfflineSched;
import com.service.scheduler.sched.PasswordSched;
import com.service.scheduler.sched.SaveGpsSched;
import com.service.scheduler.sched.SaveWorkChangeSched;
import com.service.scheduler.sched.SubSpeedched;

public class SchedulerServer {

	private static SchedulerServer server;

	public static SchedulerServer instance() {
		if (SchedulerServer.server == null) {
			SchedulerServer.server = new SchedulerServer();
		}
		return SchedulerServer.server;
	}

	public SchedulerServer() {
		this.init();
	}

	/**
	 * 初始化任务调度管理器
	 */
	public void init() {
		new BaiduApiSched().init();
		new CacheSched().init();
		new PasswordSched().init();
		new SaveGpsSched().init();
		new SaveWorkChangeSched().init();
//		new SaveWorkSpeedSched().init();
		new FuelConsumptionAlarmSched().init();
		//报警消息发送定时器
		new NoticeMessageSched().init();

		new OfflineSched().init();
		new DutySched().init();
		
		//垃圾数据同步定时器
		new GarbageDataSyncSched().init();
		//副发累计定时更新
		new SubSpeedched().init();
	}

	/**
	 * 启动任务调度器
	 */
	public void run() {
		for (Scheduler sched : CacheManager.instance().schedMap.values()) {
			try {
				sched.start();
			} catch (SchedulerException e) {
				Logger.err(e);
			}
		}
	}

	/**
	 * 关闭任务调度器
	 */
	public void shutdown() {
		for (Scheduler sched : CacheManager.instance().schedMap.values()) {
			try {
				sched.shutdown();
				System.out.println("shutdown the scheduler [" + sched.getSchedulerName() + "]");
			} catch (SchedulerException e) {
				System.out.println(e.getMessage());
			}
		}
		CacheManager.instance().schedMap.clear();
	}

	/**
	 * 暂停任务
	 * 
	 * @param schedName
	 *            调度器名称
	 * @param jobName
	 *            任务名称
	 * @param groupName
	 *            任务组名称
	 * @return boolean
	 */
	public boolean pauseJob(String schedName, String jobName, String groupName) {
		boolean flag = false;
		try {
			Scheduler sched = CacheManager.instance().schedMap.get(schedName);
			JobKey jobKey = JobKey.jobKey(jobName, groupName);
			if (sched.checkExists(jobKey)) {
				sched.pauseJob(jobKey);
				flag = true;
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return flag;
	}

	/**
	 * 恢复任务
	 * 
	 * @param schedName
	 *            调度器名称
	 * @param jobName
	 *            任务名称
	 * @param groupName
	 *            任务组名称
	 * @return boolean
	 */
	public boolean resumeJob(String schedName, String jobName, String groupName) {
		boolean flag = false;
		try {
			Scheduler sched = CacheManager.instance().schedMap.get(schedName);
			JobKey jobKey = JobKey.jobKey(jobName, groupName);
			if (sched.checkExists(jobKey)) {
				sched.resumeJob(jobKey);
				flag = true;
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return flag;
	}

	/**
	 * 删除任务
	 * 
	 * @param schedName
	 *            调度器名称
	 * @param jobName
	 *            任务名称
	 * @param groupName
	 *            任务组名称
	 * @return boolean
	 */
	public boolean deleteJob(String schedName, String jobName, String groupName) {
		boolean flag = false;
		try {
			Scheduler sched = CacheManager.instance().schedMap.get(schedName);
			JobKey jobKey = JobKey.jobKey(jobName, groupName);
			if (sched.checkExists(jobKey)) {
				sched.deleteJob(jobKey);
				flag = true;
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return flag;
	}

	/**
	 * 立即运行任务
	 * 
	 * @param schedName
	 *            调度器名称
	 * @param jobName
	 *            任务名称
	 * @param groupName
	 *            任务组名称
	 * @return boolean
	 */
	public boolean triggerJob(String schedName, String jobName, String groupName) {
		boolean flag = false;
		try {
			Scheduler sched = CacheManager.instance().schedMap.get(schedName);
			JobKey jobKey = JobKey.jobKey(jobName, groupName);
			if (sched.checkExists(jobKey)) {
				sched.triggerJob(jobKey);
				flag = true;
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return flag;
	}

	/**
	 * 更新任务（时间表达式）
	 * 
	 * @param schedName
	 *            调度器名称
	 * @param jobName
	 *            任务名称
	 * @param groupName
	 *            任务组名称
	 * @param cronExpression
	 *            定时器时间表达式
	 * @return boolean
	 */
	public boolean rescheduleJob(String schedName, String jobName,
			String groupName, String cronExpression) {
		boolean flag = false;
		try {
			Scheduler sched = CacheManager.instance().schedMap.get(schedName);
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, groupName);
			if (sched.checkExists(triggerKey)) {
				CronTrigger trigger = (CronTrigger) sched
						.getTrigger(triggerKey);
				// 按新的cronExpression表达式重新构建trigger
				trigger = trigger
						.getTriggerBuilder()
						.withIdentity(triggerKey)
						.withSchedule(
								CronScheduleBuilder
										.cronSchedule(cronExpression)).build();
				sched.rescheduleJob(triggerKey, trigger);
				flag = true;
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return flag;
	}
	
	/**
	 * 追加监听器
	 * 
	 * @param schedName
	 *            调度器名称
	 * @param jobName
	 *            任务名称
	 * @param groupName
	 *            任务组名称
	 * @param listener
	 *            监听器
	 * @return boolean
	 */	
	public boolean addListen(String schedName, String jobName,
			String groupName,JobListener listener) {
		boolean flag = false;
		try {
			Scheduler sched = CacheManager.instance().schedMap.get(schedName);
			JobKey jobKey = JobKey.jobKey(jobName, groupName);
			if (sched.checkExists(jobKey)) {							
				Matcher<JobKey> matcher = KeyMatcher.keyEquals(jobKey); 
				sched.getListenerManager().addJobListener(listener, matcher);  
				flag = true;
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return flag;
	}
}
